﻿using System;

/*
 * 创建人：Kewin
 * 
 * 时间：2010.8.4
 * 
 * 修改说明：
 * 
 * 
 */


namespace ConsoleTest.ChapterTwelve
{
    #region Inherit
    /*结构与继承
     * 结构体不能作为基类，同时不能继承自结构体或者类。
     * 可以实现接口
     */
    public class Inherit
    {
        public static void Virtual()
        {
            Base a = new Base("");
            a.ShowName();
            Derived b = new Derived("", 1);
            b.ShowName();
        }
    }
    public class Base
    {
        private string m_name;

        
        public Base(string name)
        {
            m_name = name;
        }

        /*为何引入多态性 以及new override 与 virtual
         *我们创建了一个类所派生出来的多个类，希望能够将他们用于一个基类的过程。
         *在C#中为了使用多态性，需要在基类中使用virtual或者override关键字（总有一个基类是使用virtual）
         *，并且派生类中使用override或者override sealed 来使用多态性。
         *
         * 使用new关键字来屏蔽多态性，其实不使用new关键字多态性同样是不起作用的，使用new的原因是
         * 为了使代码更加清晰。
         */
        public   void ShowName()
        {
            System.Console.WriteLine("Base");
        }
    }
    public class Derived : Base
    {
        //编译器自动生成属性
        public int Age { get; set; }
        //访问基类的构造函数的语法，类似于C++中的成员初始化列表
        public Derived(string name,int age):base( name)
        {
            Age = age;
        }

        public  void ShowName()
        {
            System.Console.WriteLine("Derived!");
        }
    }
    #endregion

    #region Abstact

    /*抽象性
     * 
     * 为什么需要抽象？
     * 在某些继承级别，比如基类的某个方法中由于方法脱离于具体的派生类，
     * 对于该方法而言，仅仅是一个强制性的约束（约束其派生类必须有这样的功能）
     * 而没有具体的代码可写，因此引入了抽象方法（特殊的虚方法）。
     * 
     * 抽象类与抽象方法
     * C#中的抽象类可以没有抽象方法。抽象基类不能够实例化。
     */

    /*多态性
     * 通过继承，一个类可以用作多种类型：可以用作它自己的类型、任何基类型，或者在实现接口时用作任何接口类型。这称为多态性。
     * C# 中的每种类型都是多态的。类型可用作它们自己的类型或用作 Object 实例，因为任何类型都自动将 Object 当作基类型。
     */

    /*接口与Object
     * 与类和结构体不同，接口并不从Object派生。
     * 因为只有类或结构体能够实现接口，所以允许在接口变量上调用Object类的成员，前提是接口仅仅是一个指向实现体的引用。
     */

    interface I
    {
        void fct1();
        void fct2();
    }
    
    public class C : I
    {
        public void fct1() { System.Console.WriteLine("fct1 called"); }
        //强制类的使用者使用抽象体（接口的引用）而非实现体（具体类的引用）
        //即：类的使用者如果要使用接口的方法必须通过转换为接口的引用来调用方法
        //通过这种集成在语言中的技术，可以使代码的使用者与实现体之间解耦。
        //通过使用名称限定的语法 即：InterfaceName.FunctionName(){}
         void I.fct2() { System.Console.WriteLine("fct2 called"); }
    }

    public class Abstract
    {
        public static void Interface()
        {
            C refImpl = new C();
            I refAbst=(I)refImpl;
            refAbst.fct1();
            refAbst.fct2();
            refImpl.fct1();
            ((I)refImpl).fct2();//注意：如果直接使用refImpl调用fct2，编译器会报出：C没有包含fct2函数定义的错误
        }
    }
    #endregion


    ///// <summary>
    ///// 
    ///// </summary>
    //public abstract class BasedClass
    //{
    //     //        * 说明：抽象类相关概念
    //     //* （1）抽象类是不能够实例化，引入抽象类是对类的再次抽象，即提取共性，去除个性的东西；
    //     //* （2）抽象类可以不包含抽象方法；包含抽象成员的类必然是抽象类；
    //     //* （3）抽象方法其实是隐式的虚方法，抽象方法不能提供实现而是由派生类利用override关键字实现；
    //     //* （4）补充：类的静态方法尽可以访问静态成员；非静态方法可以访问静态和非静态成员和方法。

    //    public virtual void NewTestShow()
    //    {
    //        System.Console.WriteLine("Base NewTestShow");
    //    }
    //    public virtual void OverrideTestShow()
    //    {
    //        System.Console.WriteLine("Base OverrideTestShow");
    //    }
        
    //    public  abstract void AbstractTestShow();
    //    /// <summary>
    //    /// virtual的方法可以被override、也可被new
    //    /// </summary>
    //    public virtual void Function()
    //    {
    //        System.Console.WriteLine("Base Function");
    //    }
    //    public static void StaticFunction()
    //    {
    //        System.Console.WriteLine("Base StaticFunction");
    //    }
    //}
    //public class DerivedClass:BasedClass
    //{
    //    public new void NewTestShow()
    //    {
    //        System.Console.WriteLine("Derived NewTestShow");
    //    }
    //    public override void OverrideTestShow()
    //    {
    //        System.Console.WriteLine("Derived OverrideTestShow");
    //    }
    //    public new void Function()
    //    {
    //        System.Console.WriteLine("Derived Function");
    //    }
    //    /// <summary>
    //    ///
    //    /// </summary>
    //    public override void AbstractTestShow()
    //    {
    //        System.Console.WriteLine("Derived AbstractTestShow");
    //    }
    //    public static new void StaticFunction()
    //    {
    //        System.Console.WriteLine("Derived StaticFunction");
    //    }
    //}
    //public class AbstractTest
    //{
    //    public static void Test1()
    //    {
    //        BasedClass BaseEntity = new DerivedClass();
    //        BaseEntity.NewTestShow();
    //        BaseEntity.OverrideTestShow();
    //        BaseEntity.Function();
    //        DerivedClass d = new DerivedClass();
    //        d.Function();

    //    }
    //}
}